-
Notifications
You must be signed in to change notification settings - Fork 169
Refactor PkH fragment to support Pk
#431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor PkH fragment to support Pk
#431
Conversation
src/policy/compiler.rs
Outdated
| } | ||
| Concrete::Key(ref pk) => { | ||
| insert_wrap!(AstElemExt::terminal(Terminal::PkH(pk.to_pubkeyhash()))); | ||
| insert_wrap!(AstElemExt::terminal(Terminal::PkH( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally this insert_wrap should have been avoided (since we know Concrete::Key during compilation), but we have a change in internal representation for Terminal::PkH (found when one of tests fail in absence of this statement). As I understand, there can be 2 solutions:
- Implement
PartialEqforTerminal::PkHto only check equality in the fieldPk::Hash. We can still access thePkentry while having proper checks. Also, since we might require disambiguating aTerminal::PkHbased on availability ofPk,Eqcan check total equality by considering the first field too. - Keep both the compilations. Although I think this might give rise to ambiguity in the compilation and parsing miniscript from string can be an issue (internal representation of
Terminal::PkHcan't be inferred from a string representation as of now).
I'm open to any other suggestions too!
|
@apoelstra , thinking about your comment here: bitcoin/bitcoin#24114 (comment). I am thinking it would make more sense to change
|
|
I like it. We could then also change |
|
@SarcasticNastik, we need to modify this as follows:
|
4d63856 to
e322327
Compare
PkH fragment to support Pk
444b1fb to
f170aaa
Compare
sanket1729
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do another round tomorrow
src/miniscript/astelem.rs
Outdated
| Terminal::PkK(ref p) => pred(ForEach(p)), | ||
| Terminal::PkH(ref p) => todo!("KeyHash should contain Pk"), | ||
| Terminal::PkH(ref p) => pred(ForEach(p)), | ||
| Terminal::RawPkH(ref p) => todo!("Should we require to iterate over the Hashes too?"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We just ignore these. As these are not known keys.
| // alias: pk(K) = c:pk_k(K) | ||
| return write!(f, "pk({})", pk); | ||
| } else if let Terminal::PkH(ref pkh) = sub.node { | ||
| } else if let Terminal::RawPkH(ref pkh) = sub.node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can print this. But we should note in comments that RawPkH is currently unsupported in descriptor spec.
a3d2b36 to
eb5b3d1
Compare
sanket1729
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly ACK, but the history is unclean. Can you remove the previous commits?
We can do the updating the miniscript tests stuff in a follow up PR.
| ms_attributes_test("c:andor(ripemd160(6ad07d21fd5dfc646f0b30577045ce201616b9ba),pk_h(9fc5dbe5efdce10374a4dd4053c93af540211718),and_v(v:hash256(8a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b25),pk_h(dd100be7d9aea5721158ebde6d6a1fd8fff93bb1)))", "82012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba876482012088aa208a35d9ca92a48eaade6f53a64985e9e2afeb74dcf8acb4c3721e0dc7e4294b258876a914dd100be7d9aea5721158ebde6d6a1fd8fff93bb1886776a9149fc5dbe5efdce10374a4dd4053c93af5402117188868ac", true, false, true, 18, 3); | ||
| ms_attributes_test("c:andor(u:ripemd160(6ad07d21fd5dfc646f0b30577045ce201616b9ba),pk_h(20d637c1a6404d2227f3561fdbaff5a680dba648),or_i(pk_h(9652d86bedf43ad264362e6e6eba6eb764508127),pk_h(751e76e8199196d454941c45d1b3a323f1433bd6)))", "6382012088a6146ad07d21fd5dfc646f0b30577045ce201616b9ba87670068646376a9149652d86bedf43ad264362e6e6eba6eb764508127886776a914751e76e8199196d454941c45d1b3a323f1433bd688686776a91420d637c1a6404d2227f3561fdbaff5a680dba6488868ac", true, false, true, 23, 4); | ||
| ms_attributes_test("c:or_i(andor(c:pk_h(fcd35ddacad9f2d5be5e464639441c6065e6955d),pk_h(9652d86bedf43ad264362e6e6eba6eb764508127),pk_h(06afd46bcdfd22ef94ac122aa11f241244a37ecc)),pk_k(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e))", "6376a914fcd35ddacad9f2d5be5e464639441c6065e6955d88ac6476a91406afd46bcdfd22ef94ac122aa11f241244a37ecc886776a9149652d86bedf43ad264362e6e6eba6eb7645081278868672102d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e68ac", true, true, true, 17, 5); | ||
| ms_attributes_test("c:or_i(and_v(v:older(16),pk_h(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729)),pk_h(02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5))", "6360b26976a91420d637c1a6404d2227f3561fdbaff5a680dba648886776a9148f9dff39a81ee4abcbad2ad8bafff090415a2be88868ac", true, true, true, 12, 3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is okay for this PR. As a followup, we should be using the same test vectors from https://github.com/sipa/miniscript/blob/fa7ea77b19d76738addce71430cb8ff50ee846b9/bitcoin/test/miniscript_tests.cpp#L461-L475 .
Now, we don't have to manually compute the hashes here
src/lib.rs
Outdated
| Hash(&'a Pk::Hash), | ||
| } | ||
| /// Either a key or keyhash, but both contain Pk | ||
| pub struct ForEach<'a, Pk: MiniscriptKey>(&'a Pk); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to reviewers. We deliberately do not iterate over RawPkH here. In a follow-up PR, we will make Miniscript::from_ast fail when we reach a RawPkh terminal.
We can update this whenever partial descriptors are supported upstream
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 09299b0:
Shouldn't we just drop the ForEach type entirely here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember @sanket1729 and I discussed about removing this later on, but I don't see any reason why I can't do it here. I'm pushing another commit on top of 5cb2bcf to remove ForEach. If accepted, I can squash the commit anytime!
|
Follow things that we can do after this (I will do some of them):
|
Remove lifetime parameter concerning `PkH(Pk::Hash)` to `PkH(Pk)` refactor.
This change allows us to allow to refactor `Terminal::PkH(Pk::Hash)` to `Terminal::PkH(Pk)`.
eb5b3d1 to
36ff0d2
Compare
|
@apoelstra, can you have a high-level look at this? I would like to merge this first amongst all the other things that would be breaking first. |
| Terminal::PkK(ref pk) => Semantic::KeyHash(pk.to_pubkeyhash()), | ||
| Terminal::PkH(ref pkh) => Semantic::KeyHash(pkh.clone()), | ||
| Terminal::PkK(ref pk) | Terminal::PkH(ref pk) => Semantic::KeyHash(pk.to_pubkeyhash()), | ||
| Terminal::RawPkH(ref pkh) => Semantic::KeyHash(pkh.clone()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 36ff0d2:
I guess this is for a future PR, but I'd kinda like to make semantic::Policy have only Pks, not Pk::Hashes, and then refuse to lift any scripts that had RawPkH in it. We could provide a transformer that took a Miniscript<Pk> to a Miniscript<Pk::Hash> maybe, converting RawPkHs to PkHs along the way, to get the old behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, the future TODOs are listed #431 (comment)
|
ack 36ff0d2 aside from the comments i made |
The test-cases previously containing 40-byte hash for `pk_h` fragment have been replaced with 66-byte pubkey.
36ff0d2 to
5cb2bcf
Compare
Since we disregard any `Pk::Hash` as a valid iterable key, only `Pk` is considered as such. The refactor reflects directly iterating over `Pk` (a valid Miniscript Key).
apoelstra
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 8d0cf06
sanket1729
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 8d0cf06. The last commit message should be Remove ForEach struct instead of Remove ForEach trait. But won't holdoff this over that.
Thanks for keeping with the reviews
This rule is weird and wrong in a number of ways. It was introduced in PR rust-bitcoin#97 c93bdef which was the massive PR that introduced the Ctx parameter. This particular rule wasn't commented on, but we can infer some things: * From the docs on the error and my vague memory, the problem was that we couldn't estimate satisfaction for a pubkeyhash fragment because we didn't know if the key was 33 or 65 bytes ahead of time. * Therefore, the code bans this in a legacy context, but not in bare contexts (in bare contexts there is a comment saying that bare fragments "can't contain miniscript because of standardness rules" so maybe we thought about this ... but that comment has never been true, so we thought wrong..). We should've banned the fragment in bare contexts as well. * Also, while the error is called MalleablePkH, none of this has anything to do with malleability! Later, in rust-bitcoin#431, we introduced the RawPkH fragment and put a pubkey into the PkH fragment. At that point, for PkH we always knew the pubkey and could just directly compute its size using the `is_uncompressed` accessor. The RawPkH fragment was a second-class citizen which didn't even have a string serialization. At this point we should have dropped the MalleablePkH rule. Still later, in rust-bitcoin#461, we introduced `ExtParams` and the ability to parse "insane" scripts in a more flexible way, including enabling the experimental `expr_raw_raw_pkh` fragment. We then gained an error `Analyzable::ContainsRawPkh` which conceptually overlaps with `ScriptContextError::MalleablePkH` but which isn't tied to any context, just whether the user has enabled this second-class feature.
…pport `Pk`
8d0cf061e4fcc3f7784116e43b2d2afb712cd066 Remove `ForEach` Trait (Aman Rojjha)
5cb2bcffae4f5720868138eadae7b98de0d0a9bc Refactor PkH to include key. (Aman Rojjha)
09299b072e8bbb703406192239f67ada37d53798 Refactor ForEach to contain only Pk. (Aman Rojjha)
701c9ccd2c30d0c91e7b7130312caa5daaaba2da Remove un-necessary lifetimes (Aman Rojjha)
ca16bd86b9de807404bde882ef85801828d5b135 Fix formatter configuration errors with latest nightly (sanket1729)
Pull request description:
As suggested in #427, this refactor helps to incorporate musig in the codebase.
ACKs for top commit:
apoelstra:
ACK 8d0cf061e4fcc3f7784116e43b2d2afb712cd066
sanket1729:
ACK 8d0cf061e4fcc3f7784116e43b2d2afb712cd066. The last commit message should be `Remove ForEach struct` instead of `Remove ForEach trait`. But won't holdoff this over that.
Tree-SHA512: 645974d9055e0458f64e214d95a73647420d46f05246be6809ae11dbfd8dacc05500c5e9f9f1b10b532b539b2d30883c014177a33e7666aea8ae383722910ff9
As suggested in #427, this refactor helps to incorporate musig in the codebase.